package model.container;

/**
 * OfferedCourseContainer.java
 * Purpose: A container to hold offered course objects
 * 
 * @author Hans Brems
 * @version 1.0 14/11/2011
 */

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import model.Course;
import model.OfferedCourse;
import model.Registration;
import model.Teacher;

public class OfferedCourseContainer {

	private static OfferedCourseContainer offeredCourseContainer;

	private List<OfferedCourse> offeredCourses;

	/* Make sure the class cannot be instantiated */
	private OfferedCourseContainer() {
		this.offeredCourses = new ArrayList<OfferedCourse>();
	}

	/** Constructs a new offered course container object if none exists */
	public static OfferedCourseContainer getInstance() {
		if (offeredCourseContainer == null) {
			offeredCourseContainer = new OfferedCourseContainer();
		}
		return offeredCourseContainer;
	}

	/** Return the list of offered courses */
	public List<OfferedCourse> getCourses() {
		return offeredCourses;
	}
	
	/** Sets the list of offered courses */
	public void setOfferedCourses(List<OfferedCourse> courses) {
		this.offeredCourses = courses;
	}
	
	/** ?????????????? */
	public void finishCourseInitialisation() {
		//CourseGenerator.finishCourseInitialisation();
	}

	/** Returns the number of courses in the container */
	public int getCourseCount() {
		return offeredCourses.size();
	}

	/** Clear the container */
	public void clear() {
		offeredCourses.clear();
	}

	/** Add an offered course to the list */
	public void addOfferedCourse(OfferedCourse course) {
		offeredCourses.add(course);
	}

	/** Removes an offered course from the list */
	public void removeOfferedCourse(OfferedCourse course) {
		offeredCourses.remove(course);
	}

	/** Prints all offered courses in the collection */
	public String printAllOfferedCourses() {
		String s = new String();
		for (OfferedCourse offeredCourse : offeredCourses) {
			s += offeredCourse.toString() + "\n";
		}
		return s;
	}
	
	/** Browse offered courses by teacher */
	public List<OfferedCourse> getOfferedCoursesForTeacher(Teacher teacher) {
		
		List<OfferedCourse> result = new ArrayList<OfferedCourse>();
		
		// Check for correct input
		if (teacher == null) {
			return null;
		}

		// Browse courses
		for (OfferedCourse offeredCourse : this.offeredCourses) {
			// Check if teacher matches the search query
			if (offeredCourse.getTeacher() == teacher) {
				result.add(offeredCourse);
			}
		}

		// Return result
		return result;
	}
	
	/**
	 * 
	 * @return a map of courses with their registrations
	 */
	public Map<String,Collection<Registration>> getOfferedCourseRegistrations(){
		Map<String,Collection<Registration>> offeredcourseRegistrationMap = new HashMap<String,Collection<Registration>>();
		List<Course> courses =CourseContainer.getInstance().getCourses();
		for(int i=0; i < courses.size(); i++){
			offeredcourseRegistrationMap.put(courses.get(i).getName(), new HashSet<Registration>());
		}
		for(int i=0; i < offeredCourses.size(); i++){
			String courseName = offeredCourses.get(i).getCourse().getName();
			offeredcourseRegistrationMap.get(courseName).addAll(offeredCourses.get(i).getRegistrations());
		}
		return offeredcourseRegistrationMap;
	}
	
	public OfferedCourse getOfferedCourseByID(Object id) {
		for (OfferedCourse offeredCourse : this.offeredCourses) {
			if (offeredCourse.getPrimaryKey().equals(id)) {
				return offeredCourse;
			}
		}
		return null;
	}
	
}